<template>
  <label class="switch" :style="style" :checked="checked">
    <input v-model="isChecked" type="checkbox" />
    <!-- 滑块 -->
    <div
      class="slider round"
      ref="slider"
      :class="{
        checked: checked
      }"
      @click="($event) => buttonClick()"
    ></div>
  </label>
</template>

<script lang="ts">
export default {
  name: 'jc-switch'
}
</script>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import type { Ref } from 'vue'

const props = defineProps({
  checked: {
    type: Boolean,
    default: false
  },
  unCheckedColor: {
    type: String,
    default: '#ffffff'
  },
  checkedColor: {
    type: String,
    default: '#cdcdcd'
  },
  sliderBgUncheck: {
    type: String,
    default: '#5bca00'
  },
  sliderBgCheck: {
    type: String,
    default: '#5bca00'
  },
  actionTime: {
    type: String,
    default: '0.1s'
  },
  switchSize: {
    type: String,
    default: '23px'
  },
  sliderSize: {
    type: String,
    default: '19px'
  }
})

const style = `--base-color:${props.unCheckedColor}; --checked-color:${props.checkedColor}; --slider-check-color:${props.sliderBgCheck}; --slider-uncheck-color:${props.sliderBgUncheck}; --action-time:${props.actionTime}; --switch-size:${props.switchSize}; --slider-size:${props.sliderSize}`
const isChecked: Ref<boolean> = ref(props.checked)

const emit = defineEmits({
  click: (evt: MouseEvent) => evt instanceof MouseEvent
})

let evt: MouseEvent

const buttonClick = () => {
  emit('click', evt)
}

onMounted(() => {
  evt = new MouseEvent('click', {
    bubbles: true,
    cancelable: true,
    view: window
  })
  if (props.checked) {
    emit('click', evt)
  }
})
</script>
<style lang="scss">
.switch {
  position: relative;
  display: inline-block;
  width: calc(var(--switch-size) * 2);
  height: var(--switch-size);

  input {
    appearance: none;

    &:checked + .slider {
      background-color: var(--checked-color);
    }

    &:focus + .slider {
      box-shadow: 0 0 1px var(--checked-color);
    }
  }

  .slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: var(--base-color);
    -webkit-transition: var(--action-time);
    transition: var(--action-time);

    &:before {
      position: absolute;
      color: #ffffff;
      content: '';
      height: var(--slider-size);
      width: var(--slider-size);
      left: 4px;
      bottom: 2px;
      -webkit-transition: var(--action-time);
      transition: var(--action-time);
      background-color: #9e4242;
    }

    &.round {
      border-radius: var(--slider-size);

      &:before {
        border-radius: 50%;
      }
    }
  }
}

input:checked + .slider:before {
  -webkit-transform: translateX(var(--slider-size));
  -ms-transform: translateX(var(--slider-size));
  transform: translateX(var(--slider-size));
}
</style>
